/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.store.client.components;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.elf.gwt.common.client.components.CommonSimpleComponent;
import com.elf.gwt.common.client.model.AdvancedSearchModel;
import com.elf.gwt.common.client.model.CategoryModel;
import com.elf.gwt.common.client.model.ManufacturerModel;
import com.elf.gwt.store.client.GWTCommerceConstants;
import com.elf.gwt.store.client.StoreComponentController;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;


/**
 * 
 */

public class AdvancedSearchComponent extends StoreSimpleComponent
{
	protected boolean lazyLoaded = false;

	protected FlowPanel bodyPanel;
	protected TextBox keywordsTextBox;
	protected CheckBox searchDescriptionsCheckBox;
	protected ListBox categoryListBox;
	protected CheckBox includeSubComponentCheckBox;
	protected ListBox manufacturerListBox;
	protected TextBox priceFromTextBox;
	protected TextBox priceToTextBox;
	protected TextBox dateFromTextBox;
	protected TextBox dateToTextBox;

	protected List<CategoryModel> categoryModelList;
	protected List<ManufacturerModel> manufacturerModelList;

	protected DateTimeFormat dtformat;
	protected AdvancedSearchModel advancedSearchModel;

	/**
	 * Constructor
	 */

	public AdvancedSearchComponent(StoreComponentController controller, String stylePrefix)
	{
		super(controller, stylePrefix, null, false);

		advancedSearchModel = new AdvancedSearchModel();

		categoryModelList = new ArrayList<CategoryModel>();
		dtformat = DateTimeFormat.getFormat(controller.getStoreConstants().AccountComponentDateOfBirthFormat());
	}

	public boolean updateFromHistoryParameters(String[] params)
	{
		updateModelFromHistoryParameters(params);
		storeController.getMultipleResultsComponent().addComponent(this);

		//Don't look for new products
		CommonSimpleComponent alwaysAskComponent = controller.getComponent("NewProductsComponent", false);
		if (alwaysAskComponent != null) storeController.getMultipleResultsComponent().removeComponent(alwaysAskComponent);
		
		return super.updateFromHistoryParameters(params);
	}


	public void updateModelFromHistoryParameters(String[] params)
	{
		int categoryId = StoreComponentController.categoriesComponent.getCategoryModel().getId();
		int manufacturerId = StoreComponentController.manufacturersComponent.getManufacturerModel().getId();
		boolean descriptionSearch = false;
		boolean includeSubCategories = false;
		boolean searchSpecials = false;
		double priceFrom = 0;
		double priceTo = 0;
		String date_from = "*";
		Date dateFrom = null;
		String date_to = "*";
		Date dateTo = null;
		int offset = 0;
		String orderby = "*";
		String keywords = "";
		
		try {
			categoryId = Integer.parseInt(params[1]);
			manufacturerId = Integer.parseInt(params[2]);
			descriptionSearch = Boolean.parseBoolean(params[3]);
			includeSubCategories = Boolean.parseBoolean(params[4]);
			searchSpecials = Boolean.parseBoolean(params[5]);
			priceFrom = Double.parseDouble(params[6]);
			priceTo = Double.parseDouble(params[7]);
			date_from = params[8];
			date_to = params[9];
			offset = Integer.parseInt(params[10]);
			orderby = params[11];
			keywords = params[12];
		}
		catch (Exception e) {}

		if (!date_from.equals("*")) dateFrom = new Date(Integer.parseInt(date_from));
		if (!date_to.equals("*")) dateTo = new Date(Integer.parseInt(date_to));
		if (orderby.equals("*")) orderby = "pd.products_name";
		if (keywords.equals("*")) keywords = "";

		StoreComponentController.productComponent.getProductModel().update(0, 0, "");
		
		CategoryModel cmodel = StoreComponentController.categoriesComponent.getCategoryModel(categoryId);
		StoreComponentController.categoriesComponent.getCategoryModel().update(cmodel);
		
		if (manufacturerId != StoreComponentController.manufacturersComponent.getManufacturerModel().getId())
		{
			ManufacturerModel mmodel = StoreComponentController.manufacturersComponent.getManufacturerModelById(manufacturerId);
			StoreComponentController.manufacturersComponent.getManufacturerModel().update(mmodel);
			StoreComponentController.manufacturersComponent.rebuild();
			storeController.getMultipleResultsComponent().addComponent(StoreComponentController.categoriesComponent);
		}
		
		advancedSearchModel.clear();
		advancedSearchModel.setDescriptionSearch(descriptionSearch);
		advancedSearchModel.setIncludeSubCategories(includeSubCategories);
		advancedSearchModel.setSearchSpecials(searchSpecials);
		advancedSearchModel.setPriceFrom(priceFrom);
		advancedSearchModel.setPriceTo(priceTo);
		advancedSearchModel.setDateFrom(dateFrom);
		advancedSearchModel.setDateTo(dateTo);
		advancedSearchModel.setOffset(offset);
		advancedSearchModel.setOrderby(orderby);
		advancedSearchModel.setKeywords(keywords);
	}
	
	public void build()
	{
		if (! lazyLoaded)lazyLoad();
		CategoryModel cmodel = StoreComponentController.categoriesComponent.getCategoryModel(0);
		categoryModelList.clear();
		buildCategoryListBox(cmodel,"");
		manufacturerModelList = StoreComponentController.manufacturersComponent.getManufacturerModels();
		buildManufacturerListBox(manufacturerModelList);

		panel.setWidget(1, 0, bodyPanel);

		onBuilt();
	}

	protected void lazyLoad()
	{
		if (lazyLoaded) return;

		lazyLoaded = true;
		GWTCommerceConstants constants = storeController.getStoreConstants();
		CellFormatter cf;

		//Body Panel
		bodyPanel = new FlowPanel();
		bodyPanel.setWidth("100%");
		bodyPanel.setStyleName("ComponentBodyPanel");
		bodyPanel.addStyleName(getHandle() + "BodyPanel");

		//Search Critieria		
		Grid keywordsPanel = new Grid(2,1);
		keywordsPanel.setWidth("100%");
		keywordsPanel.setStyleName(getHandle() + "KeywordsPanel");
		cf = keywordsPanel.getCellFormatter();
		cf.setStyleName(0, 0, getHandle() + "KeywordsPanelTitle");
		cf.setStyleName(1, 0, getHandle() + "KeywordsPanelBody");

		Grid keywordsBodyPanel = new Grid(2,1);
		keywordsBodyPanel.setWidth("100%");
		cf = keywordsBodyPanel.getCellFormatter();
		cf.setStyleName(0, 0, getHandle() + "KeywordsPanelInput");
		cf.setStyleName(1, 0, getHandle() + "KeywordsPanelDescription");
		cf.setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_RIGHT);
		cf.setWidth(0, 0, "100%");
		cf.setWidth(1, 0, "100%");

		keywordsPanel.setText(0, 0, constants.AdvancedSearchComponentKeywordsPanelTitle());
		keywordsPanel.setWidget(1, 0, keywordsBodyPanel);

		keywordsTextBox = new TextBox();
		keywordsTextBox.setWidth("100%");
		Grid keywordsDescriptionsPanel = new Grid(1,2);
		searchDescriptionsCheckBox = new CheckBox();
		searchDescriptionsCheckBox.setValue(false);
		keywordsDescriptionsPanel.setWidget(0, 0, searchDescriptionsCheckBox);
		keywordsDescriptionsPanel.setText(0, 1, constants.AdvancedSearchComponentDescriptionSearch());

		keywordsBodyPanel.setWidget(0, 0, keywordsTextBox);
		keywordsBodyPanel.setWidget(1, 0, keywordsDescriptionsPanel);

		//Search Button
		Grid searchPanel = new Grid(1,2);
		searchPanel.setStyleName(getHandle() + "SearchPanel");
		cf = searchPanel.getCellFormatter();
		cf.setStyleName(0, 0, getHandle() + "SearchPanelHelp");
		cf.setStyleName(0, 1, getHandle() + "SearchPanelButton");
		cf.setHorizontalAlignment(0, 1, HasHorizontalAlignment.ALIGN_RIGHT);
		cf.setWidth(0, 0, "100%");

		Button searchButton = new Button(constants.AdvancedSearchComponentSearch(), clickHandler);
		InlineLabel helpLabel = new InlineLabel(constants.AdvancedSearchComponentHelp());
		helpLabel.setStyleName("ComponentLink");
		searchPanel.setWidget(0, 0, helpLabel);
		searchPanel.setWidget(0, 1, searchButton);

		//Advanced
		Grid advancedPanel = new Grid(10,4);
		cf = advancedPanel.getCellFormatter();
		advancedPanel.setStyleName(getHandle() + "AdvancedPanel");
		for (int i = 0;i<advancedPanel.getRowCount(); i++)
		{
			cf.setWidth(i, 0, "5px");
			advancedPanel.setHTML(i, 0, "&nbsp;");
			cf.setStyleName(i, 1, getHandle() + "AdvancedPanelLabel");
			cf.setStyleName(i, 2, getHandle() + "AdvancedPanelValue");
			cf.setWidth(i, 3, "100%");
			advancedPanel.setHTML(i, 3, "&nbsp;");
		}

		categoryListBox = new ListBox();

		Grid includeSubComponentPanel = new Grid(1,2);
		includeSubComponentCheckBox = new CheckBox();
		includeSubComponentCheckBox.setValue(true);
		includeSubComponentPanel.setWidget(0, 0, includeSubComponentCheckBox);
		includeSubComponentPanel.setText(0, 1, constants.AdvancedSearchComponentIncludeCategories());

		manufacturerListBox = new ListBox();

		priceFromTextBox = new TextBox();
		priceToTextBox = new TextBox();

		Grid dateFromPanel = new Grid(1,2);
		dateFromTextBox = new TextBox();
		dateFromPanel.setWidget(0, 0, dateFromTextBox);
		dateFromPanel.setText(0, 1, dtformat.getPattern());
		Grid dateToPanel = new Grid(1,2);
		dateToTextBox = new TextBox();
		dateToPanel.setWidget(0, 0, dateToTextBox);
		dateToPanel.setText(0, 1, dtformat.getPattern());

		advancedPanel.setText(0, 1, constants.AdvancedSearchComponentCategory());
		advancedPanel.setText(3, 1, constants.AdvancedSearchComponentManufacturer());
		advancedPanel.setText(5, 1, constants.AdvancedSearchComponentPriceFrom());
		advancedPanel.setText(6, 1, constants.AdvancedSearchComponentPriceTo());
		advancedPanel.setText(8, 1, constants.AdvancedSearchComponentDateFrom());
		advancedPanel.setText(9, 1, constants.AdvancedSearchComponentDateTo());

		advancedPanel.setWidget(0, 2, categoryListBox);
		advancedPanel.setWidget(1, 2, includeSubComponentPanel);
		advancedPanel.setWidget(3, 2, manufacturerListBox);
		advancedPanel.setWidget(5, 2, priceFromTextBox);
		advancedPanel.setWidget(6, 2, priceToTextBox);
		advancedPanel.setWidget(8, 2, dateFromPanel);
		advancedPanel.setWidget(9, 2, dateToPanel);

		bodyPanel.add(keywordsPanel);
		bodyPanel.add(searchPanel);
		bodyPanel.add(advancedPanel);
	}

	protected void buildCategoryListBox(CategoryModel cmodel, String prefix)
	{		
		categoryListBox.addItem(prefix + cmodel.getName(),String.valueOf(cmodel.getId()));
		categoryModelList.add(cmodel);
		List<CategoryModel> children = cmodel.getChildList();
		Iterator<CategoryModel> iter = children.iterator();
		while(iter.hasNext())
		{
			CategoryModel child = iter.next();
			buildCategoryListBox(child, prefix + "+");
		}
	}

	protected void buildManufacturerListBox(List<ManufacturerModel> manufacturerModels)
	{		
		manufacturerListBox.clear();
		Iterator<ManufacturerModel> iter = manufacturerModels.iterator();
		while(iter.hasNext())
		{
			ManufacturerModel mmodel = iter.next();
			manufacturerListBox.addItem(mmodel.getName(),String.valueOf(mmodel.getId()));
		}
	}

	protected ClickHandler clickHandler = new ClickHandler() {
		public void onClick(ClickEvent event) {
			String history = getHistory();
			
			onSelection(history);

		}
	};

	public String getHistory()
	{
		String history = "AdvancedSearchResultsComponent--";

		int index = categoryListBox.getSelectedIndex();
		CategoryModel categoryModel = categoryModelList.get(index);
		history += categoryModel.getId() + "--";

		index = manufacturerListBox.getSelectedIndex();
		ManufacturerModel manufacturerModel = manufacturerModelList.get(index);
		history += manufacturerModel.getId() + "--";
		history += searchDescriptionsCheckBox.getValue() + "--";
		history += includeSubComponentCheckBox.getValue() + "--false--";

		String strPriceFrom = priceFromTextBox.getText();
		if (strPriceFrom != null && strPriceFrom.length() > 0) {
			try
			{
				double priceFrom = Double.parseDouble(priceFromTextBox.getText());
				strPriceFrom = String.valueOf(priceFrom);
			}
			catch(Exception exception) {
				strPriceFrom = "0";
			}
		}
		else {
			strPriceFrom = "0";
		}
		history += strPriceFrom + "--";

		String strPriceTo = priceToTextBox.getText();
		if (strPriceTo != null && strPriceTo.length() > 0) {
			try
			{
				double priceTo = Double.parseDouble(priceToTextBox.getText());
				strPriceTo = String.valueOf(priceTo);
			}
			catch(Exception exception) {
				strPriceTo = "0";
			}
		}
		else {
			strPriceTo = "0";
		}
		history += strPriceTo + "--";

		String strDateFrom = dateFromTextBox.getText();
		if (strDateFrom != null && strDateFrom.length() > 0)
		{
			try
			{
				Date dateFrom = dtformat.parse(strDateFrom);
				strDateFrom = String.valueOf(dateFrom.getTime());
			}
			catch(Exception exception) {
				strDateFrom = "*";
			}
		}
		else {
			strDateFrom = "*";
		}
		history += strDateFrom + "--";

		String strDateTo = dateToTextBox.getText();
		if (strDateTo != null && strDateTo.length() > 0)
		{
			try
			{
				Date dateTo = dtformat.parse(strDateTo);
				strDateTo = String.valueOf(dateTo.getTime());
			}
			catch(Exception exception) {
				strDateTo = "*";
			}
		}
		else {
			strDateTo = "*";
		}
		history += strDateTo + "--0--*--";

		String keywords = keywordsTextBox.getText();
		if (keywords == null || keywords.length() == 0) keywords = "*";
		history += keywords;
		
		return history;
	}
	
	public AdvancedSearchModel getAdvancedSearchModel() {
		return advancedSearchModel;
	}


}
